package notification

import (
	"encoding/json"
	"gitee.com/mjun1833/buildnotification/config"
	"gitee.com/mjun1833/buildnotification/entity"
	"gitee.com/mjun1833/buildnotification/model"
	"gitee.com/mjun1833/buildnotification/utils/dgtime"
	"gitee.com/mjun1833/buildnotification/utils/idbuilder"
)

// 根据订阅信息创建请求对象
func BuildSubscribeNotificationArrReq(subscribe *entity.Subscribe, dataType model.DataType, data interface{}, apeID, tollgateID string) *model.CreateSubscribeNotificationArrReq {
	reqMap := &model.CreateSubscribeNotificationArrReq{}
	subscribeNotifications := &model.SubscribeNotification{
		Title:          subscribe.Title,
		TriggerTime:    dgtime.GetNowTimeStr(),
		SubscribeID:    subscribe.SubscribeID,
		NotificationID: idbuilder.GetBusinessObjectID(idbuilder.BusinessSubTypeSubscribeNotification),
	}
	reqMap.SubscribeNotificationListObject.SubscribeNotificationObject = append(reqMap.SubscribeNotificationListObject.SubscribeNotificationObject, subscribeNotifications)

	switch dataType {
	case model.DataTypePerson:
		temp := data.(*model.Person)
		temp.PersonID = idbuilder.GetImageCntObjectID(apeID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypePerson)
		temp.DeviceID = apeID
		temp.ShotTime = dgtime.GetNowTimeStr()
		if temp.SubImageList != nil && len(temp.SubImageList.SubImageInfoObject) != 0 {
			for i := range temp.SubImageList.SubImageInfoObject {
				temp.SubImageList.SubImageInfoObject[i].ShotTime = dgtime.GetNowTimeStr()
			}
		}

		if reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].PersonObjectList == nil {
			reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].PersonObjectList = &model.PersonListObject{}
		}
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].PersonObjectList.PersonObject = append(reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].PersonObjectList.PersonObject, temp)
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].InfoIDs = temp.PersonID
	case model.DataTypeFace:
		temp := data.(*model.Face)
		temp.FaceID = idbuilder.GetImageCntObjectID(apeID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypeFace)
		temp.DeviceID = apeID
		temp.ShotTime = dgtime.GetNowTimeStr()
		if temp.SubImageList != nil && len(temp.SubImageList.SubImageInfoObject) != 0 {
			for i := range temp.SubImageList.SubImageInfoObject {
				temp.SubImageList.SubImageInfoObject[i].ShotTime = dgtime.GetNowTimeStr()
			}
		}

		if reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].FaceObjectList == nil {
			reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].FaceObjectList = &model.FaceListObject{}
		}
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].FaceObjectList.FaceObject = append(reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].FaceObjectList.FaceObject, temp)
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].InfoIDs = temp.FaceID
	case model.DataTypeMotorVehicle:
		temp := data.(*model.MotorVehicle)
		temp.MotorVehicleID = idbuilder.GetImageCntObjectID(apeID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypeMotorVehicle)
		temp.DeviceID = apeID
		temp.TollgateID = tollgateID
		temp.ShotTime = dgtime.GetNowTimeStr()
		temp.PassTime = dgtime.GetNowTimeStr()
		temp.AppearTime = dgtime.GetNowTimeStr()
		temp.DisappearTime = dgtime.GetNowTimeStr()
		if temp.SubImageList != nil && len(temp.SubImageList.SubImageInfoObject) != 0 {
			for i := range temp.SubImageList.SubImageInfoObject {
				temp.SubImageList.SubImageInfoObject[i].ShotTime = dgtime.GetNowTimeStr()
			}
		}

		if reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].MotorVehicleObjectList == nil {
			reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].MotorVehicleObjectList = &model.MotorVehicleListObject{}
		}
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].MotorVehicleObjectList.MotorVehicleObject = append(reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].MotorVehicleObjectList.MotorVehicleObject, temp)
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].InfoIDs = temp.MotorVehicleID
	case model.DataTypeNonMotorVehicle:
		temp := data.(*model.NonMotorVehicle)
		temp.NonMotorVehicleID = idbuilder.GetImageCntObjectID(apeID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypeNonMotorVehicle)
		temp.DeviceID = apeID
		temp.AppearTime = dgtime.GetNowTimeStr()
		temp.DisappearTime = dgtime.GetNowTimeStr()
		if temp.SubImageList != nil && len(temp.SubImageList.SubImageInfoObject) != 0 {
			for i := range temp.SubImageList.SubImageInfoObject {
				temp.SubImageList.SubImageInfoObject[i].ShotTime = dgtime.GetNowTimeStr()
			}
		}

		if reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].NonMotorVehicleObjectList == nil {
			reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].NonMotorVehicleObjectList = &model.NonMotorVehicleListObject{}
		}
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].NonMotorVehicleObjectList.NonMotorVehicleObject = append(reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].NonMotorVehicleObjectList.NonMotorVehicleObject, temp)
		reqMap.SubscribeNotificationListObject.SubscribeNotificationObject[0].InfoIDs = temp.NonMotorVehicleID
	}

	return reqMap
}

func BuildSubscribeNotificationArrReq2(subscribe *entity.Subscribe, tempNotifications *model.CreateSubscribeNotificationArrReq, apeID, tollgateID string, isBuild, isBulidTime, isBuildApeExtend bool, addTimestamp int64) (*model.CreateSubscribeNotificationArrReq, []model.DataType, error) {
	// 深拷贝，防止修改了原始数据
	marshal, err := json.Marshal(tempNotifications)
	if err != nil {
		return nil, nil, err
	}
	notifications := &model.CreateSubscribeNotificationArrReq{}
	err = json.Unmarshal(marshal, notifications)
	if err != nil {
		return nil, nil, err
	}

	dataTypes := make([]model.DataType, 0)

	for _, subscribeNotification := range notifications.SubscribeNotificationListObject.SubscribeNotificationObject {
		if isBuild {
			subscribeNotification.Title = subscribe.Title
			subscribeNotification.SubscribeID = subscribe.SubscribeID
			subscribeNotification.NotificationID = idbuilder.GetBusinessObjectID(idbuilder.BusinessSubTypeSubscribeNotification)
			timeStr, err := dgtime.TimeStrAddTimestamp(subscribeNotification.TriggerTime, addTimestamp)
			if err != nil {
				return nil, nil, err
			}
			subscribeNotification.TriggerTime = timeStr
		}

		if subscribeNotification.FaceObjectList != nil && len(subscribeNotification.FaceObjectList.FaceObject) != 0 {
			temps := subscribeNotification.FaceObjectList.FaceObject
			for i := range temps {
				if isBuild {
					tempDeviceID := ""
					tempShotTimeStr := ""
					if isBulidTime {
						timeStr, err := dgtime.TimeStrAddTimestamp(temps[i].ShotTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].ShotTime = timeStr
						tempShotTimeStr = timeStr
					}
					if isBuildApeExtend {
						//if _, ok := entity.ApeMap[temps[i].DeviceID]; !ok {
						//	temps[i].DeviceID = apeID
						//}
						temps[i].DeviceID = apeID
						tempDeviceID = temps[i].DeviceID
					}
					if isBulidTime && isBuildApeExtend {
						temps[i].FaceID = idbuilder.GetImageCntObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypeFace)
					}
					if !isValidTime(temps[i].ShotTime) {
						return nil, nil, nil
					}

					if temps[i].SubImageList != nil && len(temps[i].SubImageList.SubImageInfoObject) != 0 {
						for j := range temps[i].SubImageList.SubImageInfoObject {
							if isBuildApeExtend {
								//if _, ok := entity.ApeMap[temps[i].SubImageList.SubImageInfoObject[j].DeviceID]; !ok {
								//	temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
								//}
								temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
							}
							if isBulidTime {
								timeStr, err := dgtime.TimeStrAddTimestamp(temps[i].SubImageList.SubImageInfoObject[j].ShotTime, addTimestamp)
								if err != nil {
									return nil, nil, err
								}
								temps[i].SubImageList.SubImageInfoObject[j].ShotTime = timeStr
							}
							if isBulidTime && isBuildApeExtend {
								temps[i].SubImageList.SubImageInfoObject[j].ImageID = idbuilder.GetImageObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage)
							}
						}
					}
				}

				dataTypes = append(dataTypes, model.DataTypeFace)
			}
			subscribeNotification.InfoIDs = temps[0].FaceID
			subscribeNotification.FaceObjectList.FaceObject = temps
		}

		if subscribeNotification.PersonObjectList != nil && len(subscribeNotification.PersonObjectList.PersonObject) != 0 {
			temps := subscribeNotification.PersonObjectList.PersonObject
			for i := range temps {
				if isBuild {
					tempDeviceID := ""
					tempShotTimeStr := ""
					if isBuildApeExtend {
						//if _, ok := entity.ApeMap[temps[i].DeviceID]; !ok {
						//	temps[i].DeviceID = apeID
						//}
						temps[i].DeviceID = apeID
						tempDeviceID = temps[i].DeviceID
					}
					if isBulidTime {
						timeStr, err := dgtime.TimeStrAddTimestamp(temps[i].ShotTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].ShotTime = timeStr
						tempShotTimeStr = timeStr
					}
					if isBulidTime && isBuildApeExtend {
						temps[i].PersonID = idbuilder.GetImageCntObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypePerson)
					}
					if !isValidTime(temps[i].ShotTime) {
						return nil, nil, nil
					}

					if temps[i].SubImageList != nil && len(temps[i].SubImageList.SubImageInfoObject) != 0 {
						for j := range temps[i].SubImageList.SubImageInfoObject {
							if isBuildApeExtend {
								//if _, ok := entity.ApeMap[temps[i].SubImageList.SubImageInfoObject[j].DeviceID]; !ok {
								//	temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
								//}
								temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
							}
							if isBulidTime {
								timeStr, err := dgtime.TimeStrAddTimestamp(temps[i].SubImageList.SubImageInfoObject[j].ShotTime, addTimestamp)
								if err != nil {
									return nil, nil, err
								}
								temps[i].SubImageList.SubImageInfoObject[j].ShotTime = timeStr
							}
							if isBulidTime && isBuildApeExtend {
								temps[i].SubImageList.SubImageInfoObject[j].ImageID = idbuilder.GetImageObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage)
							}
						}
					}
				}

				dataTypes = append(dataTypes, model.DataTypePerson)
			}

			subscribeNotification.InfoIDs = temps[0].PersonID
			subscribeNotification.PersonObjectList.PersonObject = temps
		}

		if subscribeNotification.MotorVehicleObjectList != nil && len(subscribeNotification.MotorVehicleObjectList.MotorVehicleObject) != 0 {
			temps := subscribeNotification.MotorVehicleObjectList.MotorVehicleObject

			for i := range temps {
				if isBuild {
					tempDeviceID := ""
					tempShotTimeStr := ""
					if isBuildApeExtend {
						//if _, ok := entity.ApeMap[temps[i].DeviceID]; !ok {
						//	temps[i].DeviceID = apeID
						//}
						//if _, ok := entity.TollgateMap[temps[i].TollgateID]; !ok {
						//	temps[i].TollgateID = tollgateID
						//}
						temps[i].DeviceID = apeID
						temps[i].TollgateID = tollgateID
						tempDeviceID = temps[i].DeviceID
					}
					if isBulidTime {
						shotTimeStr, err := dgtime.TimeStrAddTimestamp(temps[i].ShotTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].ShotTime = shotTimeStr

						passTimeStr, err := dgtime.TimeStrAddTimestamp(temps[i].PassTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].PassTime = passTimeStr
						tempShotTimeStr = passTimeStr

						appearTimeStr, err := dgtime.TimeStrAddTimestamp(temps[i].AppearTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].AppearTime = appearTimeStr

						disAppearTimeStr, err := dgtime.TimeStrAddTimestamp(temps[i].DisappearTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].DisappearTime = disAppearTimeStr
					}
					if isBulidTime && isBuildApeExtend {
						temps[i].MotorVehicleID = idbuilder.GetImageCntObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypeMotorVehicle)
					}
					if !isValidTime(temps[i].PassTime) {
						return nil, nil, nil
					}

					if temps[i].SubImageList != nil && len(temps[i].SubImageList.SubImageInfoObject) != 0 {
						for j := range temps[i].SubImageList.SubImageInfoObject {
							if isBuildApeExtend {
								//if _, ok := entity.ApeMap[temps[i].SubImageList.SubImageInfoObject[j].DeviceID]; !ok {
								//	temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
								//}
								temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
							}
							if isBulidTime {
								timeStr, err := dgtime.TimeStrAddTimestamp(temps[i].SubImageList.SubImageInfoObject[j].ShotTime, addTimestamp)
								if err != nil {
									return nil, nil, err
								}
								temps[i].SubImageList.SubImageInfoObject[j].ShotTime = timeStr
							}
							if isBulidTime && isBuildApeExtend {
								temps[i].SubImageList.SubImageInfoObject[j].ImageID = idbuilder.GetImageObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage)
							}
						}
					}
				}

				dataTypes = append(dataTypes, model.DataTypeMotorVehicle)
			}

			subscribeNotification.InfoIDs = temps[0].MotorVehicleID
			subscribeNotification.MotorVehicleObjectList.MotorVehicleObject = temps
		}

		if subscribeNotification.NonMotorVehicleObjectList != nil && len(subscribeNotification.NonMotorVehicleObjectList.NonMotorVehicleObject) != 0 {
			temps := subscribeNotification.NonMotorVehicleObjectList.NonMotorVehicleObject
			for i := range temps {
				if isBuild {
					tempDeviceID := ""
					tempShotTimeStr := ""
					if isBuildApeExtend {
						//if _, ok := entity.ApeMap[temps[i].DeviceID]; !ok {
						//	temps[i].DeviceID = apeID
						//}
						temps[i].DeviceID = apeID
						tempDeviceID = temps[i].DeviceID
					}
					if isBulidTime {
						appearTimeStr, err := dgtime.TimeStrAddTimestamp(temps[i].AppearTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].AppearTime = appearTimeStr
						tempShotTimeStr = appearTimeStr

						disAppearTimeStr, err := dgtime.TimeStrAddTimestamp(temps[i].DisappearTime, addTimestamp)
						if err != nil {
							return nil, nil, err
						}
						temps[i].DisappearTime = disAppearTimeStr
					}
					if isBulidTime && isBuildApeExtend {
						temps[i].NonMotorVehicleID = idbuilder.GetImageCntObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage, idbuilder.ImageCntObjectIDTypeMotorVehicle)
					}

					if !isValidTime(temps[i].AppearTime) {
						return nil, nil, nil
					}

					if temps[i].SubImageList != nil && len(temps[i].SubImageList.SubImageInfoObject) != 0 {
						for j := range temps[i].SubImageList.SubImageInfoObject {
							if isBuildApeExtend {
								//if _, ok := entity.ApeMap[temps[i].SubImageList.SubImageInfoObject[j].DeviceID]; !ok {
								//	temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
								//}
								temps[i].SubImageList.SubImageInfoObject[j].DeviceID = apeID
							}
							if isBulidTime {
								timeStr, err := dgtime.TimeStrAddTimestamp(temps[i].SubImageList.SubImageInfoObject[j].ShotTime, addTimestamp)
								if err != nil {
									return nil, nil, err
								}
								temps[i].SubImageList.SubImageInfoObject[j].ShotTime = timeStr
							}
							if isBulidTime && isBuildApeExtend {
								temps[i].SubImageList.SubImageInfoObject[j].ImageID = idbuilder.GetImageObjectIDByTimeStr(tempShotTimeStr, tempDeviceID, idbuilder.VideoSubTypeImage)
							}
						}
					}
				}

				dataTypes = append(dataTypes, model.DataTypeNonMotorVehicle)
			}

			subscribeNotification.InfoIDs = temps[0].NonMotorVehicleID
			subscribeNotification.NonMotorVehicleObjectList.NonMotorVehicleObject = temps
		}
	}

	return notifications, dataTypes, nil
}

func isValidTime(timeStr string) bool {
	if timeStr == "" || len(timeStr) < 7 {
		return false
	}

	minTimeStr := config.GetInstance().GetString("buildConf.minTime")
	maxTimeStr := config.GetInstance().GetString("buildConf.maxTime")

	dayStr := timeStr[:8]
	if dayStr >= minTimeStr && dayStr <= maxTimeStr {
		return true
	}

	return false
}
